home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 41.zip / BS1 part 41 / Amiga Plus 1.adf / Programming / menustuf.c < prev    next >
C/C++ Source or Header  |  1978-04-08  |  12KB  |  457 lines

  1. /* :ts=8 */
  2. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  3. /*                                                              */
  4. /*      MenuStuf.c                                              */
  5. /*                                                              */
  6. /*      Menu routines for AmigaPLUS article about Intuition    */
  7. /*      Written by Michael G. Lehman                            */
  8. /*      of Intuitive Technologies                               */
  9. /*                                                              */
  10. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  11.  
  12.  
  13. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  14. /*      Complete Include file for Amiga programs                */
  15. /*      Derived from examples supplied by Commodore Amiga       */
  16. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  17.  
  18.  
  19. #include <exec/types.h>
  20. #include <exec/nodes.h>
  21. #include <exec/lists.h>
  22. #include <exec/memory.h>
  23. #include <exec/ports.h>
  24. #include <exec/tasks.h>
  25. #include <exec/libraries.h>
  26. #include <exec/devices.h>
  27. #include <exec/io.h>
  28. #include <exec/devices.h>
  29.  
  30. #include <libraries/dos.h>
  31.  
  32. #include <graphics/gfx.h> /* ALWAYS INCLUDE GFX.H before other includes */
  33. #include <graphics/display.h>
  34. #include <graphics/clip.h>
  35. #include <graphics/rastport.h>
  36. #include <graphics/gfxbase.h>
  37. #include <graphics/text.h>
  38. #include <graphics/regions.h>
  39. #include <graphics/copper.h>
  40. #include <graphics/gels.h>
  41.  
  42. #include <devices/inputevent.h>
  43. #include <devices/gameport.h>
  44. #include <devices/console.h>
  45. #include <devices/keymap.h>
  46.  
  47. #define int32 long
  48. #define int16 int
  49.  
  50. #include <intuition/intuition.h>
  51. struct XMenuItem                /* our extended menu structure */
  52. {
  53.         struct XMenuItem *NextItem;
  54.         SHORT LeftEdge, TopEdge;
  55.         SHORT Width, Height;
  56.         USHORT Flags;
  57.         LONG MutualExclude;
  58.         APTR ItemFill;
  59.         APTR SelectFill;
  60.         BYTE Command;
  61.         struct XMenuItem *SubItem;
  62.         USHORT NextSelect;
  63.         int (*ItemHndlr)();     /* all above is standard and we add this */
  64. };
  65.  
  66.  
  67. extern UBYTE * AllocMem();
  68.  
  69. #define SECONDS io_Actual
  70. #define MICROSECONDS io_Length
  71. #define PUBCLEAR MEMF_CHIP | MEMF_CLEAR
  72.  
  73. struct Menu *NewMenu();
  74. struct XMenuItem *AddItem();
  75. struct XMenuItem *AddSubItem();
  76.  
  77. extern struct Window *Mwindow;  /* currently chosen window and screen for */
  78. extern struct Screen *Mscreen; /* this menu build operation               */
  79.  
  80. #define ITEMSTD         ITEMTEXT | ITEMENABLED | HIGHCOMP
  81. #define CHKITEMSTD      ITEMSTD | CHECKIT
  82.  
  83. /****************************************************************/
  84. /*                                                              */
  85. /*      NewMenu                                                 */
  86. /*      Build a menu header                                     */
  87. /*      LeftEdge automatically calcuated if passed as -1        */
  88. /*      Width automatically calculated if passed as -1          */
  89. /*                                                              */
  90. /*      Returns pointer to the Menu for calling AddItem         */
  91. /*                                                              */
  92. /****************************************************************/
  93.  
  94. struct Menu *NewMenu(root,left,top,width,height,flags,title)
  95. struct Menu *root;
  96. int32 left,top,width,height,flags;
  97. register char *title;
  98. {
  99.  
  100.   register int32 i;
  101.   register struct Menu *p;
  102.   register struct Menu *p2;
  103.  
  104.   p = AllocMem(sizeof(struct Menu),PUBCLEAR);
  105.   p2 = NULL;
  106.  
  107.   if (root != NULL)
  108.     {
  109.         p2 = root /* -> NextMenu */ ;
  110.         while(p2->NextMenu !=NULL)
  111.           p2 = p2 -> NextMenu;
  112.     }
  113.  
  114.   if (p2 != NULL)
  115.     p2 -> NextMenu = p;
  116.  
  117.   p -> NextMenu         = NULL;
  118.   if (left == -1 && p2 != NULL)
  119.     p -> LeftEdge = p2 -> LeftEdge + p2 -> Width + 6;
  120.   else
  121.     p -> LeftEdge       = left;
  122.   p -> TopEdge          = top;
  123.   if (width == -1)
  124.     p -> Width = TextLength(&Mscreen -> RastPort,title,strlen(title))+10;
  125.   else
  126.     p -> Width          = width;
  127.   p -> Height           = height;
  128.   p -> Flags            = flags;
  129.   p -> FirstItem        = NULL;
  130.   p -> MenuName         = title;
  131.  
  132.   return(p);
  133. }
  134.  
  135. /****************************************************************/
  136. /*                                                              */
  137. /*      AddItem                                                 */
  138. /*      Add a menu item to a menu list                          */
  139. /*      Width and Height automatically calculated               */
  140. /*                                                              */
  141. /*      Returns pointer to the item for calling AddSubItem      */
  142. /*                                                              */
  143. /****************************************************************/
  144.  
  145. struct XMenuItem *AddItem(mp,flags,text,handler,cmdchar)
  146. struct Menu *mp;
  147. int32 flags;
  148. char *text;
  149. int32 (*handler)(); /* subroutine to handle this menu item */
  150. char cmdchar;   /* valid only if flags & COMMSEQ is true */
  151. {
  152.   register struct XMenuItem *mp2;
  153.   register struct XMenuItem *mi;
  154.   register struct IntuiText *ip;
  155.  
  156.   register int32 i;
  157.   int32 maxwidth;
  158.  
  159.   i = 0;
  160.  
  161.  
  162.   if (mp -> FirstItem != NULL)
  163.     {
  164.       mp2 = mp -> FirstItem;
  165.       i++;
  166.       while(mp2 -> NextItem != NULL)
  167.         {
  168.           i++;
  169.           mp2 = mp2 -> NextItem;        /* get to the bottom of the list */
  170.         }
  171.     }
  172.   else
  173.     mp2 = NULL; /* so our debug stuff doesn't blow up */
  174.  
  175.   mi = AllocMem(sizeof(struct XMenuItem),PUBCLEAR);/*this zeroes it as well */
  176.   ip = (struct IntuiText *) AllocMem(sizeof(struct IntuiText),PUBCLEAR);
  177.   ip -> FrontPen = 0;
  178.   ip -> BackPen = Mwindow -> BlockPen;
  179.   ip -> DrawMode = JAM2;
  180.   ip -> LeftEdge = 0;
  181.   ip -> TopEdge  = 1;
  182.   ip -> ITextFont = NULL;
  183.   ip -> NextText = NULL;
  184.   ip -> IText = text;
  185.  
  186.   mi -> NextItem = NULL;
  187.   mi -> LeftEdge = 0;
  188.   mi -> TopEdge  = /*12*/ 9 * i;        /* standard height = 12 lines */
  189.   mi -> Width = IntuiTextLength(ip);
  190.   if (flags & COMMSEQ)
  191.     mi -> Width += COMMWIDTH;
  192.   mi -> Height= /*12*/ 9;               /* standard height = 12 lines */
  193.   mi -> Flags = flags;
  194.   mi -> MutualExclude = 0;
  195.   mi -> ItemFill =  (APTR) ip;
  196.   mi -> SelectFill = NULL;
  197.   mi -> Command = 0;
  198.   mi -> SubItem = NULL;
  199.   mi -> NextSelect = 0;
  200.   mi -> ItemHndlr = handler;
  201.   if (flags & COMMSEQ)
  202.     mi -> Command = cmdchar;
  203.  
  204.   if (i == 0)
  205.     mp -> FirstItem = mi;
  206.   else
  207.     mp2 -> NextItem = mi;
  208.  
  209.   /* now run the menu list looking for the widest */
  210.   mp2 = mp -> FirstItem;
  211.   maxwidth = mp2 -> Width;
  212.  
  213.   while(mp2 -> NextItem != NULL)
  214.     {
  215.         mp2 = mp2 -> NextItem;
  216.         if (mp2 -> Width > maxwidth)
  217.           maxwidth = mp2 -> Width;
  218.     }
  219.  
  220.   if (maxwidth <= mp -> Width)
  221.     maxwidth = mp -> Width;
  222.  
  223.   /* now set all items to the max width */
  224.   mp2 = mp -> FirstItem;
  225.   while(mp2 != NULL)
  226.     {
  227.         mp2 -> Width = maxwidth;
  228.         mp2 = mp2 -> NextItem;
  229.     }
  230.  
  231.   SetMaximumWidth(mp);
  232.  
  233.   return(mi);
  234. }
  235.  
  236. /****************************************************************/
  237. /*                                                              */
  238. /*      AddSubItem                                              */
  239. /*      Add a sub menu item to a menu item                      */
  240. /*      Width and Height automatically calculated               */
  241. /*                                                              */
  242. /*      Returns pointer for adding sub-sub items                */
  243. /*                                                              */
  244. /****************************************************************/
  245.  
  246. struct XMenuItem *AddSubItem(mp,flags,text,cmdchar)
  247. struct XMenuItem *mp;
  248. int32 flags;
  249. char *text;
  250. char cmdchar;   /* valid only if flags & COMMSEQ is true */
  251. {
  252.   register struct XMenuItem *mp2;
  253.   register struct XMenuItem *mi;
  254.   register struct IntuiText *ip;
  255.  
  256.   register int32 i;
  257.   int32 maxwidth;
  258.  
  259.   i = 0;
  260.  
  261.   if (mp -> SubItem != NULL)
  262.     {
  263.       mp2 = mp -> SubItem;
  264.       i++;
  265.       while(mp2 -> NextItem != NULL)
  266.         {
  267.           i++;
  268.           mp2 = mp2 -> NextItem;        /* get to the bottom of the list */
  269.         }
  270.     }
  271.  
  272.   mi = AllocMem(sizeof(struct XMenuItem),PUBCLEAR);/* this zeroes it as well */
  273.   ip = (struct IntuiText *) AllocMem(sizeof(struct IntuiText),PUBCLEAR);
  274.   ip -> FrontPen = 0;
  275.   ip -> BackPen = Mwindow -> BlockPen;
  276.   ip -> DrawMode = JAM2;
  277.   ip -> LeftEdge = 0;
  278.   ip -> TopEdge  = 1;
  279.   ip -> ITextFont = NULL;
  280.   ip -> NextText = NULL;
  281.   ip -> IText = text;
  282.  
  283.   mi -> NextItem = NULL;
  284.   mi -> LeftEdge = mp -> LeftEdge + mp -> Width -2;
  285.   mi -> TopEdge  = /*12*/ 9 * i;        /* standard height = 12 lines */
  286.   mi -> Width = IntuiTextLength(ip);
  287.   if (flags & COMMSEQ)
  288.     mi -> Width += COMMWIDTH;
  289.   mi -> Height= /*12*/ 9;               /* standard height = 12 lines */
  290.   mi -> Flags = flags;
  291.   mi -> MutualExclude = 0;
  292.   mi -> ItemFill =  (APTR) ip;
  293.   mi -> SelectFill = NULL;
  294.   mi -> Command = 0;
  295.   mi -> SubItem = NULL;
  296.   mi -> ItemHndlr = mp -> ItemHndlr; /* copy from the parent menu */
  297.   mi -> NextSelect = 0;
  298.   if (flags & COMMSEQ)
  299.     mi -> Command = cmdchar;
  300.  
  301.   if (i == 0)
  302.     mp -> SubItem = mi;
  303.   else
  304.     mp2 -> NextItem = mi;
  305.  
  306.   /* now run the menu list looking for the widest */
  307.   mp2 = mp -> SubItem;
  308.   maxwidth = mp2 -> Width;
  309.   while(mp2 -> NextItem != NULL)
  310.     {
  311.         mp2 = mp2 -> NextItem;
  312.         if (mp2 -> Width > maxwidth)
  313.           maxwidth = mp2 -> Width;
  314.     }
  315.  
  316.   /* now set all items to the max width */
  317.   mp2 = mp -> SubItem;
  318.   while(mp2 != NULL)
  319.     {
  320.         mp2 -> Width = maxwidth;
  321.         mp2 = mp2 -> NextItem;
  322.     }
  323.  
  324.   return(mi);
  325. }
  326.  
  327.  
  328. /****************************************************************/
  329. /*                                                              */
  330. /*      UnMakeMenuStrip(rmp)                                    */
  331. /*                                                              */
  332. /*      Takes as input a "root menu pointer" i.e. the pointer   */
  333. /*      from the Window record                                  */
  334. /*      calls as needed:                                        */
  335. /*              UnMakeMenu                                      */
  336. /*              UnMakeItem                                      */
  337. /*              UnMakeSubItem                                   */
  338. /****************************************************************/
  339.  
  340. void UnMakeMenu();
  341. void UnMakeItem();
  342. void UnMakeSubItem();
  343.  
  344. void UnMakeMenuStrip(rmp)
  345. struct Menu *rmp;
  346. {
  347.   register struct Menu *mp,*mp2;
  348.  
  349.   if (rmp == NULL)
  350.     return;
  351.   mp = rmp;
  352.  
  353.   while(mp)
  354.     {
  355.       mp2 = mp -> NextMenu;
  356.       UnMakeMenu(mp);                   /* deallocate each menu in turn */
  357.       mp = mp2;
  358.     }
  359. }
  360.  
  361. void UnMakeMenu(mp)
  362. struct Menu *mp;
  363. {
  364.   register struct XMenuItem *mip,*mip2;
  365.  
  366.   if (mp == NULL)
  367.     return;
  368.   mip = mp -> FirstItem;
  369.  
  370.   while(mip)
  371.     {
  372.       mip2 = mip -> NextItem;
  373.       UnMakeItem(mip);
  374.       mip = mip2;
  375.     }
  376.   FreeMem(mp,sizeof(struct Menu));
  377. }
  378.  
  379. void UnMakeSubItem(mip)
  380. struct XMenuItem *mip;
  381. {
  382.   if (mip == NULL)
  383.     return;
  384.   FreeMem(mip -> ItemFill,sizeof(struct IntuiText));
  385.   FreeMem(mip, sizeof(struct XMenuItem));
  386. }
  387.  
  388. int32 ScanForMaxWidth(Menu)
  389.   struct Menu *Menu;
  390. {
  391.   register int32 width = 0;
  392.   register struct XMenuItem *MenuItem;
  393.  
  394.   MenuItem = Menu -> FirstItem;
  395.  
  396.   while ( MenuItem ) {
  397.  
  398.     if ( MenuItem -> Width > width ) width = MenuItem -> Width;
  399.  
  400.     MenuItem = MenuItem -> NextItem;
  401.  
  402.   }
  403.  
  404.   return ( width );
  405.  
  406. }
  407.  
  408. SetMaximumWidth(Menu)
  409.   struct Menu *Menu;
  410. {
  411.   register struct XMenuItem *MenuItem,*SubMenu;
  412.   int32 MaxWidth;
  413.  
  414.   MaxWidth = ScanForMaxWidth ( Menu );
  415.  
  416.   MenuItem = Menu -> FirstItem;
  417.  
  418.   while ( MenuItem ) {
  419.  
  420.     SubMenu = MenuItem -> SubItem;
  421.  
  422.     while ( SubMenu ) {
  423.  
  424.       SubMenu -> LeftEdge = MaxWidth;
  425.       SubMenu = SubMenu -> NextItem;
  426.  
  427.     }
  428.  
  429.     MenuItem -> Width = MaxWidth;
  430.  
  431.     MenuItem = MenuItem -> NextItem;
  432.  
  433.   }
  434.  
  435. }
  436.  
  437. void UnMakeItem(mip)
  438. struct MenuItem *mip;
  439. {
  440.   register struct MenuItem *mip2,*mip3;
  441.  
  442.   if (mip == NULL)
  443.     return;
  444.  
  445.   mip2 = mip -> SubItem;
  446.   while(mip2)
  447.     {
  448.       mip3 = mip2 -> NextItem;
  449.       UnMakeSubItem(mip2);
  450.       mip2 = mip3;
  451.     }
  452.  
  453.   FreeMem(mip -> ItemFill,sizeof(struct IntuiText));
  454.   FreeMem(mip, sizeof(struct XMenuItem));
  455. }
  456.  
  457.